From 97983b40c293016cb4761b676985f012fc29f159 Mon Sep 17 00:00:00 2001 From: "kaf24@scramble.cl.cam.ac.uk" Date: Wed, 30 Jul 2003 18:43:28 +0000 Subject: [PATCH] bitkeeper revision 1.384 (3f2811d05XH-ocmJE7ybblgMy3Q92A) network.c, dev.c, perfc_defn.h: Networking fixes. --- xen/include/xeno/perfc_defn.h | 1 + xen/net/dev.c | 2 + .../arch/xeno/drivers/network/network.c | 49 ++++++++++++------- 3 files changed, 33 insertions(+), 19 deletions(-) diff --git a/xen/include/xeno/perfc_defn.h b/xen/include/xeno/perfc_defn.h index 7d2377c19f..a4dfc6b8e1 100644 --- a/xen/include/xeno/perfc_defn.h +++ b/xen/include/xeno/perfc_defn.h @@ -9,6 +9,7 @@ PERFCOUNTER_CPU( sched_run1, "sched: calls to schedule" ) PERFCOUNTER_CPU( sched_run2, "sched: runs through scheduler" ) PERFCOUNTER_CPU( sched_ctx, "sched: context switches" ) +PERFCOUNTER( net_hypercalls, "network hypercalls" ) PERFCOUNTER( net_rx_capacity_drop, "net rx capacity drop" ) PERFCOUNTER( net_rx_delivered, "net rx delivered" ) PERFCOUNTER( net_rx_tlbflush, "net rx tlb flushes" ) diff --git a/xen/net/dev.c b/xen/net/dev.c index f31219734f..ec761a5710 100644 --- a/xen/net/dev.c +++ b/xen/net/dev.c @@ -1811,6 +1811,8 @@ long do_net_update(void) u8 *g_data; unsigned short protocol; + perfc_incr(net_hypercalls); + for ( idx = 0; idx < MAX_DOMAIN_VIFS; idx++ ) { if ( (vif = current->net_vif_list[idx]) == NULL ) diff --git a/xenolinux-2.4.21-sparse/arch/xeno/drivers/network/network.c b/xenolinux-2.4.21-sparse/arch/xeno/drivers/network/network.c index d14f08a8f1..06d06e96f3 100644 --- a/xenolinux-2.4.21-sparse/arch/xeno/drivers/network/network.c +++ b/xenolinux-2.4.21-sparse/arch/xeno/drivers/network/network.c @@ -64,6 +64,8 @@ struct net_private spinlock_t tx_lock; unsigned int idx; /* Domain-specific index of this VIF. */ + unsigned int rx_bufs_to_notify; + /* * {tx,rx}_skbs store outstanding skbuffs. The first entry in each * array is an index into a chain of free entries. @@ -111,6 +113,7 @@ static int network_open(struct net_device *dev) return 0; } + np->rx_bufs_to_notify = 0; np->rx_resp_cons = np->tx_resp_cons = np->tx_full = 0; memset(&np->stats, 0, sizeof(np->stats)); spin_lock_init(&np->tx_lock); @@ -165,12 +168,9 @@ static void network_tx_buf_gc(struct net_device *dev) unsigned int i; struct net_private *np = dev->priv; struct sk_buff *skb; - unsigned long flags; unsigned int prod; tx_entry_t *tx_ring = np->net_ring->tx_ring; - spin_lock_irqsave(&np->tx_lock, flags); - do { prod = np->net_idx->tx_resp_prod; @@ -196,8 +196,6 @@ static void network_tx_buf_gc(struct net_device *dev) np->tx_full = 0; netif_wake_queue(dev); } - - spin_unlock_irqrestore(&np->tx_lock, flags); } @@ -230,19 +228,26 @@ static void network_alloc_rx_buffers(struct net_device *dev) np->net_ring->rx_ring[i].req.id = (unsigned short)id; np->net_ring->rx_ring[i].req.addr = virt_to_machine(get_ppte(skb->head)); - } - /* - * We may have allocated buffers which have entries outstanding in - * the page update queue -- make sure we flush those first! - */ - flush_page_update_queue(); + np->rx_bufs_to_notify++; + } - np->net_idx->rx_req_prod = i; + if ( np->rx_bufs_to_notify > (RX_MAX_ENTRIES/4) ) + { + /* + * We may have allocated buffers which have entries outstanding in the + * page update queue -- make sure we flush those first! + */ + flush_page_update_queue(); - np->net_idx->rx_event = RX_RING_INC(np->rx_resp_cons); + np->net_idx->rx_req_prod = i; + + np->net_idx->rx_event = RX_RING_INC(np->rx_resp_cons); + + HYPERVISOR_net_update(); - HYPERVISOR_net_update(); + np->rx_bufs_to_notify = 0; + } } @@ -272,7 +277,6 @@ static int network_start_xmit(struct sk_buff *skb, struct net_device *dev) netif_stop_queue(dev); return -ENOBUFS; } - i = np->net_idx->tx_req_prod; if ( (((unsigned long)skb->data & ~PAGE_MASK) + skb->len) >= PAGE_SIZE ) { @@ -284,6 +288,10 @@ static int network_start_xmit(struct sk_buff *skb, struct net_device *dev) skb = new_skb; } + spin_lock_irq(&np->tx_lock); + + i = np->net_idx->tx_req_prod; + id = GET_ID_FROM_FREELIST(np->tx_skbs); np->tx_skbs[id] = skb; @@ -294,18 +302,18 @@ static int network_start_xmit(struct sk_buff *skb, struct net_device *dev) np->net_idx->tx_req_prod = TX_RING_INC(i); atomic_inc(&np->tx_entries); - np->stats.tx_bytes += skb->len; - np->stats.tx_packets++; + network_tx_buf_gc(dev); - spin_lock_irq(&np->tx_lock); if ( atomic_read(&np->tx_entries) >= TX_MAX_ENTRIES ) { np->tx_full = 1; netif_stop_queue(dev); } + spin_unlock_irq(&np->tx_lock); - network_tx_buf_gc(dev); + np->stats.tx_bytes += skb->len; + np->stats.tx_packets++; HYPERVISOR_net_update(); @@ -316,12 +324,15 @@ static int network_start_xmit(struct sk_buff *skb, struct net_device *dev) static void network_interrupt(int irq, void *dev_id, struct pt_regs *ptregs) { unsigned int i; + unsigned long flags; struct net_device *dev = (struct net_device *)dev_id; struct net_private *np = dev->priv; struct sk_buff *skb; rx_resp_entry_t *rx; + spin_lock_irqsave(&np->tx_lock, flags); network_tx_buf_gc(dev); + spin_unlock_irqrestore(&np->tx_lock, flags); again: for ( i = np->rx_resp_cons; -- 2.30.2